perm filename ARMDDT.PAL[AL,HE] blob sn#240049 filedate 1977-02-21 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00016 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002	DEFINITIONS OF ASSEMBLY CONSTANTS AND MACROS
C00007 00003	START, SAMPLE, UNXDAC, UNXADC, UNXALM, UNXKBD, UNXCRT
C00009 00004	ALLCHN, LABELS
C00012 00005
C00013 00006	OUTTAB,OUTSTR
C00016 00007	ADCSER, KBDSER, DACSER, ALMSER
C00018 00008	CLKSER
C00021 00009	DRVSQ:	DEC DRVCTR		TIME TO PLAY WITH A DAC SAMPLE?
C00023 00010	CRTSER, CRTGO, CRTWAT, CRTYET
C00026 00011	NXTLIN
C00029 00012	FLAG AND TEMP CELLS
C00033 00013	MACROS "CHANS", "CH"
C00035 00014	TABLES, CURSOR MOVE LIST
C00037 00015	OCTIN
C00038 00016	LSPACE=.	ESTABLISH NAME FOR BEGINNING OF LITERAL SPACE FOR DDT PURPOSES
C00039 ENDMK
C⊗;
;DEFINITIONS OF ASSEMBLY CONSTANTS AND MACROS

.IF1
   .TITLE VARIOUS ARM CONTROLLER EXERCISES
   .TITLE PASS 1
   .TITLE MESSAGE "LITCTR UNDEFINED" IN THIS PASS MAY BE IGNORED
.ENDC
.IF2
   .TITLE PASS 2
.ENDC


;THE FOLLWING MACRO, "LIT", IMPLEMENTS LITERALS USING AN ARTIFICIAL SECOND
;LOCATION COUNTER. THIS IS A NECESSARY EVIL AS LONG AS THE ASSEMBLER (IN THIS
;CASE, MIT-AI'S PALX), DOESN'T HAVE MULTIPLE LOCATION COUNTERS OR A LITERAL
;PSEUDO-OP.  THE ARGUMENT IS THE VALUE OF THE LITERAL. A POINTER TO THE LITERAL THUS
;CREATED IS DEPOSITED AT THE VALUE OF THE LOCATION COUNTER WHEN "LIT" WAS
;CALLED. THE LITERAL LOCATION COUNTER IS NORMALLY DEFINED TO BE THE VALUE OF THE
;ASSEMBLER'S LOCATION COUNTER AT THE END OF THE SOURCE CODE.

.MACR LIT A

    LITCTR	   ;ASSEMBLE ADDRESS OF LITERAL WE'RE ABOUT TO DEPOSIT

    SAVLOC=.       ;SAVE CURRENT LOCATION COUNTER

   .=LITCTR

    A              ;STORE LITERAL ARGUMENT

    LITCTR=.

   .=SAVLOC        ;RESTORE PREVIOUS LOCATION COUNTER
.ENDM;LIT

.=1000

INITPS:	.WORD 340	;INITIAL PROGRAM STATUS WORD=7
RUNPS:	.WORD 140	;RUN STATUS=3

CRLF:	.ASCIZ /
/

.EVEN
PROMT1:	.ASCIZ	/ADC CHANNEL NUMBER (OCTAL, 0-77) ? /

INTENB=100
PR3=140
PR4=200
PR5=240
PR6=300
PR7=340


DACVEC=130
ADCVEC=134
ALMVEC=200
CRTVEC=64
KBDVEC=60
CLKVEC=104


DAC=174000
BRAKE=174002
ADCSR=174004
ADCDAT=174006
TDAC=174010	;TEST DAC ADDRESS

R0=%0
R1=%1
R2=%2
R3=%3
R4=%4
R5=%5
SP=%6
PC=%7

PSW=177776
LIGHTS=177570
SWITCH=LIGHTS

HCOR=160000
DDT=HCOR-30000
OREG=HCOR-2
IREG=HCOR-4
DDTPSW=HCOR-12

KBDCSR=177560
KBDDAT=177562
CRTCSR=177564
CRTDAT=177566
CLKCSR=172540
CLKCSB=172542
CLKCTR=172544

CAD=16		;CURSOR ADDRESS CHARACTER

DRESET=20	;ARM ERROR CONDITION RESET BIT (IN DAC)
HOLD=101	;ADC HOLD, CONVERT, AND INTERRUPT OPERATION
LINCLK=115	;BITS TO MAKE CLOCK INTERRUPT CONTINUOUSLY AT 60HZ

;START, SAMPLE, UNXDAC, UNXADC, UNXALM, UNXKBD, UNXCRT

START:	RESET			;SET UP DEFAULT INTERRUPT SERVICE, STACK, AND PSW
	MOV #UNXDAC,DACVEC
	MOV #UNXADC,ADCVEC
	MOV #UNXALM,ALMVEC
	MOV #UNXKBD,KBDVEC
	MOV #UNXCRT,CRTVEC
	MOV #UNXCLK,CLKVEC
	CLR CLKVEC+2
	CLR DACVEC+2
	CLR ADCVEC+2
	CLR ALMVEC+2
	CLR KBDVEC+2
	CLR CRTVEC+2
	MOV #600,SP
	MOV INITPS,PSW		;INITIAL PROGRAM STATUS
	JMP ALLCHN

 
UNXCLK:	MOV #'⊃,OREG
	RTI

UNXDAC:	MOV #'∩,OREG	;SEND FUNNY CHARACTER TO LET HIM KNOW WE WERE HERE
	RTI

UNXADC:	MOV #'∪,OREG
	RTI

UNXALM:	MOV #'⊂,OREG
	RTI

UNXKBD:	MOV #'≡,OREG
	RTI

UNXCRT:	MOV #'⊗,OREG
	RTI

INCHK:	TSTB KBDCSR
	BEQ INCHK1
	CLRB KBDDAT
	JMP DDT
INCHK1:	RTS PC

;ALLCHN, LABELS
;	ALL CHANNEL BACKGROUND MODE ADC DISPLAY ROUTINE.

ALLCHN:	MOV #ADCSER,ADCVEC	;SET UP INTERRUPT VECTOR ADDRESSES
	MOV #DACSER,DACVEC
	MOV #CLKSER,CLKVEC
	MOV #ALMSER,ALMVEC
	MOV #PR7,ADCVEC+2	;ADC SERVICE STARTS RUNNING AT LEVEL 7
	MOV #PR7,DACVEC+2	;DAC    "       "      "     "   "   "
	MOV #PR3,CRTVEC+2	;SCREEN "       "      "     "   "   3
	MOV #PR7,CLKVEC+2	;CLOCK SERVICE RUNS AT LEVEL 7
	MOV #PR7,ALMVEC+2	;ALARM  "	"   "   "    "
	MOV #PR3,PSW		;ALLOW US TO BE INTERRUPTED
	MOV #HOMCLR,R0		;ADDRESS OF HOME-SHLUFF-EOS-SHLUFF SEQUENCE
	MOV #10.,R1		;NUMBER OF CHARS IN SEQUENCE
	JSR PC,OUTTAB		;VACATE SCREEN
	MOV #SAMCT,R0		;SET UP TO CLEAR SAMPLE AND
	MOV #SAMPLE,R1		; "LAST VALUE DISPLAYED" TABLES.
ALLCH1:	CLR (R1)+		;INITIALIZE "SAMPLE" AND "LAST" ARRAYS--SETTING
	MOV #1,SAMCT+SAMCT-2(R1) ;THEM TO DIFFERENT VALUES ASSURES THAT ADC CHANNELS
	SOB R0,ALLCH1		; READING ZERO WILL BE DISPLAYED
	MOV #LABTBL,R2		;R2 POINTS TO STRING ADDRESSES
	MOV #MAXLIN,R3		; AND R3 COUNTS LINES
LABEL1:	MOV (R2)+,R0		;ADDRESS OF STRING
	JSR PC,OUTSTR		;PRINT STRING
	MOV #FILL,R0		;ADDRESS OF FILL CHARACTERS
	MOV #4,R1		;NUMBER OF FILL CHARACTERS
	JSR PC,OUTTAB		;SEND FILL CHARACTERS
	SOB R3,LABEL1		;LAST STRING?
	JSR PC,CRTWAT		;YES, NOW WE MUST WAIT UNTIL CRT PROCESS IS DONE
	MOV #PR7,PSW		;DISABLE INTERRUPTS FOR A WHILE
	CLR CLKCSB		;INTERRUPT EVERY TICK
	MOV #LINCLK,CLKCSR	;INITIALIZE CLOCK-60HZ CONTINUOUS
	CLR LINCT		;INITIALIZE SCREEN COUNTERS USED BY
	CLR CHRCT		; INTERRUPT PROCESS
	MOV #CRTSER,CRTVEC	;SET UP SCREEN VECTOR
	MOV #PR3,CRTVEC+2
	MOV #INTENB,CRTCSR	;MAKE CRT WANT TO INTERRUPT
	CLR ADCBSY		;INITIALIZE BUSY FLAGS FOR ADC
	CLR DACBSY		; AND DAC
	MOVB #20,DAC		;RESET ERROR CONDITION IN DAC INTERFACE

	TST DDTFLG		;DOES HE WANT TO RUN DDT?
	BNE DDTGO		;YES, DO IT
	MOV #PR3,PSW		;NO, ALLOW US TO BE INTERRUPTED
WATLOP:	TSTB KBDCSR		; AND WAIT FOR HIM TO HIT THE VT05 KEYBOARD
	BPL WATLOP
	CLR KBDDAT		;RESET KEYBOARD DONE FLAG
	BPT
	BR STOP

DDTGO:	MOV #PR3,DDTPSW		;FIX DDT SO IT CAN BE INTERRUPTED
	BPT			;WAKE IT UP
STOP:	MOV #PR7,PSW		;GIVE HIM SOME CODE THAT MAKES IT EASY
	MOV #PR7,DDTPSW		; TO STOP THE WORLD
	RESET
	BPT
	JMP START		;AND THEN RESTART IT LATER
;OUTTAB,OUTSTR

;OUTTAB IS CALLED WITH A JSR PC,OUTTAB FROM A ROUTINE WHICH HAS SET
;UP R0 AND R1 WITH THE ADDRESS AND LENGTH OF A TABLE OF BYTES TO BE SENT
;TO THE SCREEN. CONTROL IS RETURNED TO THE ROUTINE WHEN THE TABLE IS EXHAUSTED.
;OUTSTR IS LIKE OUTTAB, EXCEPT ONLY R0 IS SET UP, AND OUTPUT TERMINATES WHEN A
;ZERO BYTE IS ENCOUNTERED

OUTSTR:	JSR PC,CRTWAT		;WAIT FOR CRT TO BECOME AVAILABLE
	MOV #OUTSR1,CRTVEC	;SET UP DISPATCH
	BR OUTTB2

OUTTAB:	JSR PC,CRTWAT		;COULD DO SOMETHING USEFUL HERE, IF DESIRED
	MOV #OUTTB1,CRTVEC	;SET UP DISPATCH
	MOV R1,OUTCTR		;SET UP CHARACTER COUNTER
OUTTB2:	MOV R0,OUTPTR		;SET UP CHARACTER POINTER
	MOV #PR4,CRTVEC+2	;RUN INTERRUPT PROCESS AT AT LEVEL 4
	DEC CRTBSY		;SET CRT BUSY FLAG
	CLR CRTCSR		;TOGGLE CRT INTERRUPT ENABLE TO START
	MOV #INTENB,CRTCSR	; INTERRUPT ROUTINE
	RTS PC			;GO BACK AND LET HIM DO OTHER STUFF


OUTSR1:	MOVB @OUTPTR,CRTDAT	;SEND NEXT CHARACTER, IS IT ZERO?
	BR OUTTB3		;YES

OUTTB1:	MOVB @OUTPTR,CRTDAT	;SEND NEXT CHARACTER
	DEC OUTCTR		;END OF TABLE ?
OUTTB3:	BEQ OUTDON		;YES, GO CLEAR FLAG AND LEAVE
	INC OUTPTR		;ADVANCE POINTER
	RTI

OUTDON:	MOV #OUTLST,CRTVEC	;SET UP TO TERMINATE AFTER NEXT INTERRUPT
	RTI

OUTLST:	CLR CRTBSY		;TELL WORLD WE'RE DONE
	CLR CRTCSR		;DISABLE INTERRUPT
	RTI
;ADCSER, KBDSER, DACSER, ALMSER

KBDSER:	CLRB KBDDAT
	DEC INTFLG
	RTI


ADCSER:	MOV ADCDAT,@SAMPTR	;STORE ADC SAMPLE IN TABLE
	DEC SAMCTR		;END OF SAMPLE LIST?
	BEQ ADCDON		;YES, GO AWAY
	ADD #2,SAMPTR		;NO, BUMP TABLE ADDRESS
	INCB ADCSR+1		;SAMPLE NEXT CHANNEL
	RTI

ADCDON:	CLR ADCSR		;CLEAR CHANNEL SELECT, INTERRUPT ENABLE, AND SET
				; FOLLOW-AND-HOLD CIRCUITS TO FOLLOW MODE
	CLR ADCBSY		;MARK ADC NOT BUSY
	RTI


DACSER:	DEC DREFCT		;END OF SAMPLE LIST?
	BMI DACSR1		;YES
	INCB DACCHN		;NO, STEP CHANNEL COUNTER
	MOVB DACCHN,DAC		;STUFF IT INTO CHANNEL REGISTER
	BISB #INTENB,DAC	;REENABLE INTERRUPT
	INC DREFPT		;STEP TABLE ADDRESS
	MOVB @DREFPT,DAC+1	; AND LOAD NEW SAMPLE
	RTI

DACSR1:	BICB #INTENB,DAC	;CLEAR DAC INTERRUPT ENABLE BIT
	CLR DACBSY		;TELL CLOCK WE'VE FINISHED
	RTI

ALMSER:	CLR DACFLG		;KILL DAC PROCESS
	MOV #'∂,OREG		;MAKE A NOISE
	RTI
;CLKSER

CLKSER:	TST CLKCSR		;DID WE MISS A TICK?
	BMI CLKERR		;YES, LET HIM KNOW
	INC CLKCNT		;STEP RANDOM TIMER
CLKSR2:	TST ADCFLG		;NO. ARE WE RUNNING THE ADC?
	BEQ NOADC		;NO, DON'T FIRE IT UP.
	TST ADCBSY		;YES. IS ADC STILL BUSY?
	BNE ADCERR		;YES, AND IT SHOULDN'T BE, SO TELL HIM.
	DEC ADCBSY		;NO, MARK IT BUSY NOW.
	MOV #SAMPLE,SAMPTR	;INITIALIZE SAMPLE TABLE POINTER
	MOV #SAMCT,SAMCTR	;INITIALIZE SAMPLE COUNTER
	MOV #HOLD,ADCSR		;START ADC WITH A HOLD OPERATION, AND CHANNEL=0
NOADC:	TST DACFLG		;ARE WE RUNNING DAC?
	BEQ NODAC		;NO, SKIP IT
	TST DACBSY		;YES. IS DAC STILL BUSY?
	BNE DACERR		;YES, TELL HIM.
	MOV #DREFTB,DREFPT	;NO, RESET DAC SAMPLE TABLE POINTER
	MOV #15.,DREFCT		; AND SAMPLE COUNTER
	CLR DACCHN		; AND CHANNEL POINTER
	BISB #INTENB+DRESET,DAC	;RESET DAC ERROR CONDITION, IF ANY
				; AND MAKE DAC WANT TO INTERRUPT
	DEC DACBSY		;MARK DAC AS BEING BUSY
	JSR PC,DRVSQ		;PLAY WITH CONTENTS OF DAC SAMPLE TABLE
NODAC:	TST CRTCLK		;IS CRT TIMER ZERO?
	BEQ CHKCRT		;YES, GO SEE IF IT WANTS TO BE AWAKENED YET
	DEC CRTCLK		;NO, DECREMENT CRT TIMER
	RTI

	DEC TDCNT	;DECREMENT TEST DAC COUNTER
	BPL TD1
	MOV #12,TDCNT	;SET COUNTER TO =10
	MOV #TDACTB,TDPTR	;SET UP TDPTR TO POINT TO TEST SAMPLE TABLE
TD1:	MOV @TDPTR,TDAC
	INC TDPTR	;STEP TEST SAMPLE POINTER
	RTI

;=.+100	;MAKE ROOM FOR HACKING

TDCNT:	.WORD 0
TDPTR:	.WORD 0
TDACTB:	.WORD 0		;STORAGE FOR DRIVE PROFILE
;=.+100

CHKCRT:	TST CRTFLG		;SEE IF SCREEN SERVICE HAS FINISHED ITS PASS
	BEQ CHKCR1		;NOT FINISHED, JUST LEAVE
	CLR CRTFLG		;FINISHED, AWAKEN IT
	MOV #INTENB,CRTCSR
CHKCR1:	RTI

CLKERR:	MOV #'∞,OREG
	BR CLKSR2

ADCERR:	MOV #'],OREG	;COMPLAIN ABOUT ADC HANGING
	CLR ADCFLG	;AND KILL ITS ASSOCIATED PROCESS
	RTI

DACERR:	MOV #'[,OREG	;MAKE A NOISE ABOUT DAC NOT BEING DONE
	CLR DACFLG	;AND DON'T TRY TO RUN DAC AGAIN
	RTI
DRVSQ:	DEC DRVCTR		;TIME TO PLAY WITH A DAC SAMPLE?
	BGE DRVSQ1		;NO, EXIT
	CMP OLDCHN,NEWCHN	;YES,HAS HE CHANGED HIS MIND ABOUT WHICH CHANNEL?
	BNE DRVSQ2		;YES, CHANGE SAMPLE
DRVSQ3:	MOV DRVCNT,DRVCTR	;NO, RESET DRIVE TIMER
	CMP OLDCHN,#7	;TEST CHANNEL?
	BNE DRVSQ4
	NEG NEWSAM		;YES, FLIP TEST DAC VALUE
;	MOV NEWSAM,NEWDAC
DRVSQ4:	NEGB @OURCHN		;FLIP SAMPLE IN CHANNEL WE'RE PLAYING WITH
DRVSQ1:	RTS PC

DRVSQ2:	CMP NEWCHN,#15.		;SEE IF IT'S A LEGAL CHANNEL
	BGT DRVSQ3		;IGNORE IF IT'S TOO HIGH
	TST NEWCHN
	BLT DRVSQ3		;OR IF IT'S TOO LOW
	CLRB @OURCHN		;ZERO THE SAMPLE WE'VE BEEN PLAYING WITH
	CMP OLDCHN,#7	;TEST CHANNEL?
	BNE DRVSQ5
;	CLR NEWDAC	;YES, ZERO IT
DRVSQ5:	MOV NEWCHN,OLDCHN	;SAVE IT SO WE CAN TELL WHEN HE CHANGES NEWCHN
	MOV OLDCHN,OURCHN
	ADD #BRAKTB,OURCHN	;FIND ADDRESS OF PROPER ENTRY IN BRAKE TABLE
	MOVB @OURCHN,BRAKE	;SET ALL BRAKES EXCEPT ON THE JOINT WE'RE RUNNING
	ADD #DSAMTB-BRAKTB,OURCHN	;NOW MAKE OURCHN POINT AT DAC SAMPLE ENTRY
	MOVB @OURCHN,TEMP	;GET DRIVE FOR THIS JOINT
	ADD #DREFTB-DSAMTB,OURCHN	;MAKE OURCHN POINT AT REFRESH TABLE ENTRY
	MOVB TEMP,@OURCHN	;AND PUT SAMPLE THERE TO BE TOGGLED
	CMP OLDCHN,#7	;TEST CHANNEL?
	BNE DRVSQ3
	MOV NEWVAL,NEWSAM;YES, DRIVE IT
	BR DRVSQ3
;CRTSER, CRTGO, CRTWAT, CRTYET

CRTSER:	DEC CHRCT		;ANY CHARACTERS LEFT ON THIS LINE?
	BMI NXTLIN		;NO, GO SET UP FOR NEXT LINE
	INC CHRPT		;POINT AT NEXT CHAR TO BE SENT
	MOV #PR4,PSW
	MOVB @CHRPT,CRTDAT	;SEND IT
	RTI			;LEAVE

CRTYET:	MOV (SP)+,R2		;RESTORE REGS
	MOV (SP)+,R0
	MOV #PR7,PSW		;LOCK OUT CLOCK SERVICE
	TST CRTCLK		;DID REFRESH RATE LIMITER COUNT TO ZERO YET?
	BEQ HOME		;YES, OK TO REFRESH SCREEN
	DEC CRTFLG		;NO, TELL CLOCK TO START US WHEN IT DOES GO TO ZERO.
	CLR CRTCSR		;CLOCK WILL AWAKEN US BY SETTING INTERRUPT BIT
	MOV #CRTGO,CRTVEC	;SET UP RESTART ENTRY
	MOV #PR7,CRTVEC+2
	RTI

CRTGO:	MOV #CRTSER,CRTVEC	;INSTALL CORRECT VECTOR
	MOV #PR3,CRTVEC+2
HOME:	MOV #16.,CRTCLK		;RESET SCREEN REFRESH RATE LIMITER
	MOV #PR3,PSW		;ALLOW CLOCK SERVICE TO RESUME
 	MOVB YINI,YCUR		;SET INITIAL CURSOR POSITION
	MOV #MAXLIN,LINCT	;INITIALIZE LINE COUNT
	MOV #CHTAB,CHTABP	;INITIALIZE CHANNEL TABLE POINTER
	MOV #LAST,LASTPT	; AND "LAST VALUE DISPLAYED" TABLE POINTER
	BR NXTLIN		;BEGIN PRINTING FIRST LINE

CRTWAT:	TST CRTBSY	;CRT STILL BUSY?
	BEQ CPOPJ	;NO, EXIT
	TST IFLAG	;YES, DOES HE WANT ME TO CHECK IF HE HAS TYPED ANYTHING?
	BEQ CRTWAT	;NO, LOOP
	TST IREG	;YES, DID HE TYPE ANYTHING?
	BEQ CRTWAT	;NO, LOOP
	CLR IREG	;YES, CLEAR WHATEVER HE TYPED
	BPT		; AND WAKE UP DDT

CPOPJ:	RTS PC
;NXTLIN

NXTLIN:	MOV R0,-(SP)		;SAVE REGISTERS WE WORK WITH
	MOV R2,-(SP)
	MOV CHTABP,R0		;GET POINTER TO ADDRESS OF NEXT CHANNEL'S SAMPLE
	MOV LASTPT,R2		; AND TO ADDRESS OF PREVIOUS SAMPLE IN THIS CHANNEL
NXTLN1:	DEC LINCT		;HAVE WE DONE THE LAST LINE?
	BMI CRTYET		;YES, GO SET UP FOR NEXT PASS DOWN SCREEN
	INCB YCUR		;NO, MOVE CURSOR DOWN ONE LINE
	CMP @(R0)+,(R2)+	;SEE IF SAMPLE HAS CHANGED
	BEQ NXTLN1		;DON'T BOTHER TO TRANSLATE IF IT HASN'T
	MOV @-2(R0),-2(R2)	;UPDATE SAMPLE VALUE IN "LAST"
	MOV R0,CHTABP		;SAVE NEW VALUE OF POINTER INTO CHANNEL TABLE
	MOV R2,LASTPT		;SAVE POINTER INTO "LAST" ARRAY
	MOV R1,-(SP)		;WE NEED ANOTHER REG FOR THE NEXT PART
	MOV #XCUR,R2		;FIRST ADDRESS OF PORTION OF STRING TO BE PRINTED
	MOVB XINI,(R2)+		;MOVE CURSOR TO SIGN POSITION
	MOVB #'+,(R2)+		;ASSUME SIGN OF SAMPLE WILL BE POS
	MOV @-2(R0),R1		;GET SAMPLE TO BE TRANSLATED
 	BPL NXTLN2		;IF SAMPLE IS POSITIVE, THEN ASSUMED SIGN IS OK
	MOVB #'-,-1(R2)		;OTHERWISE LOAD CORRECT SIGN INTO PRINT STRING
	NEG R1			; STORAGE AND MAKE SAMPLE POSITIVE
NXTLN2:	CLR R0
	ASHC #7,R0		;SHIFT FIRST OCTAL DIGIT INTO R0 FROM R1
	ADD #60,R0		;MAKE IT ASCII
	MOVB R0,(R2)+		;STORE INTO DIGIT LIST
	CLR R0			;MAKE ROOM FOR NEXT DIGIT
	ASHC #3,R0		;SECOND DIGIT
	ADD #60,R0
	MOVB R0,(R2)+
	CLR R0
	ASHC #3,R0		;THIRD DIGIT
	ADD #60,R0
	MOVB R0,(R2)+
	CLR R0
	ASHC #3,R0		;FOURTH DIGIT
	ADD #60,R0
	MOVB R0,(R2)
	MOV (SP)+,R1		;RESTORE REGS
	MOV (SP)+,R2
	MOV (SP)+,R0
	MOV #CURLST,CHRPT	;SET UP PRINT STRING ADDRESS
	MOV #DIGLEN,CHRCT	;NUMBER OF CHARS LEFT TO DO
	MOV #PR4,PSW
	MOVB @CHRPT,CRTDAT	;SEND FIRST CHARACTER
	RTI
;FLAG AND TEMP CELLS

.EVEN

 YINI:	 .BYTE 37	;INITIAL Y CURSOR POSITION-LINE 1 (MINUS 1)
 XINI:	 .BYTE 51	;INITIAL X CURSOR POSITION-COL 10
 DDTFLG: .WORD 0	;RUNS DDT AS FOREGROUND JOB IF NON-ZERO (TRUE)
 ADCFLG: .WORD 0	;RUNS ADC IF TRUE
 DACFLG: .WORD 0	;RUNS DAC IF TRUE
 TEMP:   .WORD 0	;RANDOM CELL
 CHRPT:  .WORD 0	;POINTER INTO SAMPLE CHAR STRING
 DACCHN: .WORD 0	;CHANNEL BEING UPDATED BY DACSER
 NEWCHN: .WORD 0	;PUT DAC CHANNEL NUMBER TO BE DRIVEN HERE, WITH DDT
 OLDCHN: .WORD 0	;SAVE CURRENT DAC CHANNEL HERE
 OURCHN: .WORD DREFTB	;POINTER INTO DAC REFRESH BUFFER FOR DRIVE HACK
 DRVCNT: .WORD 16	;NUMBER OF TICKS TO SKIP BETWEEN UPDATING DAC TABLE ENTRY
 DRVCTR: .WORD 0	;TIMER FOR SIMPLE MINDED DRIVE HACK--LOADED FROM DRVCNT
 DREFCT: .WORD 0	;DAC SAMPLE COUNTER
 DREFPT: .WORD 0	;POINTER TO DAC SAMPLE
 CRTFLG: .WORD 0	;LETS CLOCK KNOW CRT NEEDS TO BE AWAKENED
 CRTCLK: .WORD 0	;COUNTS MINIMUM INTERVAL BETWEEN CRT REWRITES
 LASTPT: .WORD 0	;POINTER INTO TABLE USED TO SPEED UP SCREEN ROUTINE
 CLKCNT: .WORD 0	;COUNTS CLOCK INTERRUPTS
 INTFLG: .WORD 0	;STOPS INTERRUPT PROCESSES IF≠0
 IFLAG:	 .WORD 0	;SET FROM DDT TO INDICATE BUSY-WAIT LOOP SHOULD BE LEFT
 CRTBSY: .WORD 0	;SOFTWARE BUSY FLAG FOR CRT
 ADCBSY: .WORD 0	; AND ADC
 DACBSY: .WORD 0	; AND DAC
 CHRCT:	 .WORD 0	;COUNTS DIGITS DURING TRANSLATION
 LINCT:	 .WORD 0	;COUNTS LINES TRANSLATED
 CHTBPT: .WORD 0        ;POINTER INTO CHTBL
 OUTPTR: .WORD 0        ;POINTER TO BYTE IN STRING BEING OUTPUT
 OUTCTR: .WORD 0        ;COUNTER OF BYTES IN STRING BEING OUTPUT
 LINCNT: .WORD 0        ;COUNT OF LINES DISPLAYED
 CHRCNT: .WORD 0        ;COUNT OF CHARACTERS DISPLAYED ON A LINE
 SAMPTR: .WORD 0        ;POINTER INTO ADC SAMPLE TABLE
 SAMCTR: .WORD 0        ;COUNT OF ADC SAMPLES
 CHTABP: .WORD 0	;POINTER TO CHANNEL TO BE DISPLAYED
 NEWSAM: .WORD 0	;SAMPLE IMAGE FOR TEST DAC
 NEWVAL: .WORD 0	;SAMPLE VALUE FOR TEST DAC
;MACROS "CHANS", "CH"

.MACR CHANS	;LIST OF ADC CHANNEL SAMPLE ADDRESSES AND NAMES IN ORDER DISPLAYED
 CH 17,<+REF/2>
 CH 16,<-REF/2>
 CH 21,<POT 1>
 CH 14,<POT 2>
 CH 15,<POT 3>
 CH  2,<POT 4-1>
 CH 13,<POT 4-2>
 CH  3,<POT 5>
 CH  4,<POT 6>
 CH  5,<POT 7>
 CH  0,<FINGER 1>
 CH  1,<FINGER 2>
 CH 20,<TACH 1>
 CH 10,<TACH 2>
 CH 11,<TACH 3>
 CH  6,<TACH 4>
 CH  7,<TACH 5>
.ENDM;CHANS

.MACR CH A,B		;THIS VERSION OF CH MAKES LIST OF ADC SAMPLE TABLE POINTERS
   .WORD SAMPLE+A+A	;BAGBITING PALX DOESN'T KNOW HOW TO MULTIPLY
    MAXLIN=MAXLIN+1	;COUNTS # LINES TO BE DISPLAYED
   .IFG A-MAXCHN   	;MAXCHN IS HIGHEST ADC CHANNEL NUMBER USED
       MAXCHN=A
   .ENDC;IFG
.ENDM;CH

MAXLIN=0		;INITIALIZE LINE COUNTER
MAXCHN=0		;INITIALIZE CHANNEL COUNTER
CHTAB:	CHANS

SAMCT=MAXCHN+1		;NUMBER OF ADC CHANNELS TO CONVERT
SAMPLE:	.BLKW SAMCT	;ADC CHANNEL SAMPLE STORAGE
LAST:	.BLKW SAMCT	;COMPARISON STORAGE--MUST FOLLOW SAMPLE:
;TABLES, CURSOR MOVE LIST

DSAMTB:	.BYTE 0		;DAC SAMPLE STORAGE
	.BYTE 40	;JOINT 1 (VALUES ARE NOMINAL FOR TEST PURPOSES)
	.BYTE 20	;JOINT 2
	.BYTE 20	;JOINT 3
	.BYTE 30	;JOINT 4
	.BYTE 30	;JOINT 5
	.BYTE 20	;JOINT 6
	.BYTE 20	;HAND
	.BYTE 0
	.BYTE 0
	.BYTE 0
	.BYTE 0
	.BYTE 0
	.BYTE 0
	.BYTE 0
	.BYTE 0

DREFTB: .BLKB 16.	;DAC REFRESH BUFFER

BRAKTB:	.BYTE 0,1,2,4,10,20,40,100	;BRAKE MASKS FOR ONE-JOINT OPERATION

.MACR CH A,B		;CONSTRUCT A TABLE OF POINTERS TO HEADER STRINGS
    LIT <.ASCIZ\B
\>
.ENDM;CH

LABTBL:   CHANS   ;TABLE OF POINTERS TO HEADER STRINGS


HOMCLR:	.BYTE 35,0,0,0,0,37,0,0,0,0


CURLST:	.BYTE CAD       ;STORAGE FOR CURSOR POSITION-SAMPLE PRINT SEQUENCE
YCUR:	.BYTE 0
FILL:	.BYTE 0,0,0,0
XCUR:	.BYTE 0
SIGN:	.BYTE 0
DIGITS:	.BLKB 4

DIGLEN=.-CURLST-1

.EVEN
;OCTIN


OCTIN:	CLR R1		;OCTAL INPUT ROUTINE, VALUE IN R1, USES R0 ALSO.
OCTINL:	TSTB KBDCSR
	BPL OCTINL
	MOV KBDDAT,R0
	BIC #177600,R0
	MOV R0,CRTDAT
	CMPB R0,#60
	BMI INDONE
	CMPB R0,#70
	BPL INDONE
	ASH #3,R1
	BIC #177770,R0
	BIS R0,R1
	BR OCTINL

INDONE:	CMPB R0,#15
	BNE INDON1
	MOV #5,R1
	MOV #LFNL,R0
	JSR PC,OUTTAB	;ECHO LF WHEN CR IS TYPED
INDON1:	RTS PC

 LFNL:   .BYTE 12,0,0,0,0	;LINE FEED-NULL SEQUENCE
.EVEN
LSPACE=.	;ESTABLISH NAME FOR BEGINNING OF LITERAL SPACE FOR DDT PURPOSES
LITCTR=.	;INITIALIZE LITERAL POINTER

.END START